home *** CD-ROM | disk | FTP | other *** search
- /*
- ** SpecialHost for PasTeX
- **
- ** Copyright © by Olaf Barthel & Georg Heßmann
- */
-
- #include "Global.h"
- #include "postlib.h"
-
- /*#define DEBUG*/
-
- #define INTOBP(x) ((float)(x*72.0)) /* converts 'inch' to 'big point' */
- #define INTOSP(x) ((float)(x*72.0*65781.76)) /* converts 'inch' to 'scaled point' */
- VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff);
- VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff);
-
-
-
- struct Library *PostBase;
-
- STATIC struct PSparm PSparm;
- STATIC struct BitMap *BitMap;
- STATIC PLANEPTR Plane;
- STATIC LONG ActivationRecord,
- PlaneSize;
- STATIC BOOL Transferred;
-
- #ifdef DEBUG
- STATIC struct Screen *LocalScreen;
- STATIC struct Window *LocalWindow;
- #endif /* DEBUG */
-
- extern void insertftrap(void);
- extern void deleteftrap(void);
-
- STATIC VOID __saveds
- CopyPage(VOID)
- {
- CopyMem(Plane,BitMap -> Planes[0],PlaneSize);
-
- Transferred = TRUE;
-
- #ifdef DEBUG
- if(LocalScreen)
- {
- struct IntuiMessage *IntuiMessage;
-
- CopyMem(Plane,LocalScreen -> RastPort . BitMap -> Planes[0],LocalScreen -> RastPort . BitMap -> BytesPerRow * LocalScreen -> RastPort . BitMap -> Rows);
-
- ScreenToFront(LocalScreen);
-
- WaitPort(LocalWindow -> UserPort);
-
- while(IntuiMessage = (struct IntuiMessage *)GetMsg(LocalWindow -> UserPort))
- ReplyMsg(IntuiMessage);
- }
- #endif /* DEBUG */
- }
-
- void __saveds sigfpe(void)
- {
- PSsignalfpe(ActivationRecord);
- }
-
- void __saveds sigint(void)
- {
- PSsignalint(ActivationRecord,1);
- }
-
- struct BitMap * __regargs
- ProcessPostscript(struct special_msg *Message,struct special_map *SpecialMap,struct parse_result *Result,LONG *Error)
- {
- *Error = 0;
-
- BitMap = NULL;
-
- if(PostBase = OpenLibrary("post.library",15))
- {
- BPTR NIL;
-
- if(NIL = Open("NIL:",MODE_READWRITE))
- {
- LONG NewWidth,
- NewHeight,
- X_DPI = Message -> hresolution,
- Y_DPI = Message -> vresolution;
- STRPTR special_string = NULL, sp;
-
- memset(&PSparm,0,sizeof(struct PSparm));
-
- PSGetSizeDot(Result, &NewWidth, &NewHeight, &(SpecialMap -> hoffset), &(SpecialMap -> voffset));
-
- SpecialMap -> width = NewWidth;
- SpecialMap -> height = NewHeight;
-
- PSparm . page . xoff = SpecialMap -> hoffset;
- PSparm . page . yoff = SpecialMap -> voffset;
-
- SpecialMap -> voffset = - SpecialMap -> voffset;
-
- special_string = AllocVecPooled(1024,MEMF_ANY);
- sp = special_string;
-
- sprintf(sp,"TeXDict begin %d %d 1000 %d %d (noname) @start\n", \
- (LONG) (INTOSP((float) NewWidth/(float)X_DPI) + 0.5), \
- (LONG) (INTOSP((float) NewHeight/(float)Y_DPI) + 0.5), \
- X_DPI, Y_DPI);
- sp += strlen(sp);
- sprintf(sp,"1 0 bop\nResolution neg VResolution neg vsize -72 div 1 add mul a @beginspecial\n");
- sp += strlen(sp);
-
- if(Result -> gotcontrol & GOT_HSIZE)
- {
- sprintf(sp,"%g @hsize ", INTOBP(Result -> hsize));
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_VSIZE)
- {
- sprintf(sp,"%g @vsize ", INTOBP(Result -> vsize));
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_HSCALE)
- {
- sprintf(sp,"%g @hscale ", Result -> hscale * 100.0);
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_VSCALE)
- {
- sprintf(sp,"%g @vscale ", Result -> vscale * 100.0);
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_SCALE)
- {
- sprintf(sp,"%g @hscale %g @vscale ", Result -> scale * 100.0, Result -> scale * 100.0);
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_HOFFSET)
- {
- sprintf(sp,"%g @hoffset ", INTOBP(Result -> hoffset));
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & GOT_VOFFSET)
- {
- sprintf(sp,"%g @voffset ", INTOBP(Result -> voffset));
- sp += strlen(sp);
- }
-
- if (Result -> gotcontrol & GOT_ANGLE)
- {
- sprintf(sp,"%g @angle ", Result -> angle);
- sp += strlen(sp);
- }
-
- if (Result -> gotcontrol & GOT_CLIP)
- {
- sprintf(sp,"@clip ");
- sp += strlen(sp);
- }
-
- if(Result -> gotcontrol & SUFFICIENT_PS_ARGS)
- {
- sprintf(sp,"%g @llx %g @lly %g @urx %g @ury %g @rwi ", \
- INTOBP(Result -> llx), INTOBP(Result -> lly), \
- INTOBP(Result -> urx), INTOBP(Result -> ury), \
- INTOBP(Result -> rwi));
- sp += strlen(sp);
- if(Result -> gotcontrol & GOT_RHI)
- {
- sprintf(sp,"%g @rhi ", INTOBP(Result -> rhi));
- sp += strlen(sp);
- }
- }
-
- sprintf(sp,"@setspecial\n");
- sp += strlen(sp);
-
- if(NewWidth > 30000 || NewHeight > 30000)
- *Error = ERR_TOO_LARGE;
- else
- {
- if(NewWidth < 1 || NewHeight < 1)
- *Error = ERR_TOO_SMALL;
- else
- {
- PrintLine("Page size %ld × %ld, %ld × %ld DPI",NewWidth,NewHeight,Message -> hresolution,Message -> vresolution);
-
- if(BitMap = CreateBitMap(NewWidth,NewHeight,1,NULL,NULL))
- {
- if(Plane = (PLANEPTR)AllocVecPooled(PlaneSize = BitMap -> BytesPerRow * BitMap -> Rows,MEMF_ANY))
- {
- LONG ResultCode;
-
- insertftrap();
-
- PSparm . page . depth = 1;
- PSparm . page . ydir = -1;
- PSparm . page . xden = X_DPI;
- PSparm . page . yden = Y_DPI;
- PSparm . page . xsize = NewWidth;
- PSparm . page . ysize = NewHeight;
- PSparm . page . yheight = NewHeight;
- PSparm . page . xbytes = BitMap -> BytesPerRow;
- PSparm . page . len = PSparm . page . xbytes * PSparm . page . ysize;
- PSparm . page . buf[0] = Plane;
-
- PSparm . copyfunc = (APTR)CopyPage;
- PSparm . infh = NIL;
- PSparm . outfh = NIL;
- PSparm . errfh = NIL;
-
- ActivationRecord = PScreateact(&PSparm);
-
- if(ActivationRecord <= errmax)
- {
- if(ActivationRecord)
- *Error = 20000 + ActivationRecord;
- else
- *Error = ERR_NO_MEM;
- }
- else
- {
- ULONG Flags = PSFLAGCLEAR | PSFLAGERASE;
- #ifdef DEBUG
- if(LocalScreen = OpenScreenTags(NULL,
- SA_Width, NewWidth,
- SA_Height, NewHeight,
- SA_Depth, 1,
- SA_DisplayID, HIRESLACE_KEY,
- SA_Quiet, TRUE,
- SA_AutoScroll, TRUE,
- SA_ShowTitle, FALSE,
- SA_Overscan, OSCAN_STANDARD,
- TAG_DONE))
- {
- if(!(LocalWindow = OpenWindowTags(NULL,
- WA_Left, 0,
- WA_Top, 0,
- WA_Width, LocalScreen -> Width,
- WA_Height, LocalScreen -> Height,
- WA_RMBTrap, TRUE,
- WA_Backdrop, TRUE,
- WA_Borderless, TRUE,
- WA_CustomScreen,LocalScreen,
- WA_Activate, TRUE,
- WA_IDCMP, IDCMP_VANILLAKEY,
- TAG_DONE)))
- {
- CloseScreen(LocalScreen);
-
- LocalScreen = NULL;
- }
- }
- #endif /* DEBUG */
- Transferred = FALSE;
-
- if(Result -> psinit_file[0] && !(*Error))
- {
- PrintLine("Executing initialization file...");
-
- if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_file,-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(Result -> psinit_string[0] && !(*Error))
- {
- PrintLine("Executing initialization string...");
-
- if(ResultCode = PSintstring(ActivationRecord,Result -> psinit_string,strlen(Result -> psinit_string),PSFLAGSTRING | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
- /*
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/finclude.pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/finclude.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/texps.pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/texps.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/special..pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/color.pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/color.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
- */
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/tex.pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/tex.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...","TeX:ps/special.pro");
-
- if(ResultCode = PSintstring(ActivationRecord,"TeX:ps/special.pro",-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if (!(*Error))
- {
- PrintLine("Executing special string for @beginspecial...");
- // Write(Output(),special_string,strlen(special_string));
-
- if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- if(!(*Error))
- {
- PrintLine("Executing file \"%s\"...",Result -> psfile);
-
- if(ResultCode = PSintstring(ActivationRecord,Result -> psfile,-1,PSFLAGFILE | Flags))
- *Error = 20000 + ResultCode;
- else
- {
- if(!Transferred)
- {
- if(ResultCode = PSintstring(ActivationRecord,"showpage",8,PSFLAGSTRING))
- *Error = 20000 + ResultCode;
- }
- }
- }
-
- if (!(*Error))
- {
- PrintLine("Executing special string for @endspecial...");
-
- sprintf(special_string,"@endspecial eop end userdict /end-hook known{end-hook}if\n");
- if(ResultCode = PSintstring(ActivationRecord,special_string,strlen(special_string),PSFLAGSTRING | Flags))
- *Error = 20000 + ResultCode;
- else
- Flags = NULL;
- }
-
- PSdeleteact(ActivationRecord);
- #ifdef DEBUG
- if(LocalWindow)
- {
- CloseWindow(LocalWindow);
-
- LocalWindow = NULL;
- }
-
- if(LocalScreen)
- {
- CloseScreen(LocalScreen);
-
- LocalScreen = NULL;
- }
- #endif /* DEBUG */
- }
-
- deleteftrap();
-
- FreeVecPooled(Plane);
- }
- else
- *Error = ERR_NO_MEM;
-
- if(*Error)
- {
- DeleteBitMap(BitMap);
-
- BitMap = NULL;
- }
- }
- else
- *Error = ERR_NO_MEM;
- }
- }
-
- Close(NIL);
- if (special_string) FreeVecPooled(special_string);
- }
- else
- *Error = ERR_NO_NIL;
-
- CloseLibrary(PostBase);
-
- PostBase = NULL;
- }
- else
- *Error = ERR_NO_POST;
-
- return(BitMap);
- }
-
- /* Here are some functions to get the size of the PostScript picture */
-
- #define TR_ROTATION 1
- #define TR_SCALING 2
- #define TR_TRANSLATION 3
-
- #define RAD(a) ((float)(a*3.1415926535358979324/180.0))
-
- struct ctm {
- float a,b,c,d,tx,ty;
- };
-
- struct bbox {
- float llx, lly, urx, ury;
- };
-
- STATIC void ctm_transf(struct ctm *, float, float, int);
- STATIC void point_transf(struct ctm *, float, float, float *, float *);
- STATIC void bb_new(struct ctm *, struct bbox *, struct bbox *);
-
- /* concatenates a transformation with the current transformation matrix. */
- static void ctm_transf(struct ctm *ctm, float x, float y, int transformation)
- {
- float anew, bnew, cnew, dnew, costheta, sintheta;
-
- switch (transformation) {
-
- case TR_ROTATION:
-
- costheta = cos(x);
- sintheta = sin(x);
- anew = ctm -> a * costheta + ctm -> c * sintheta;
- bnew = ctm -> b * costheta + ctm -> d * sintheta;
- cnew = - ctm -> a * sintheta + ctm -> c * costheta;
- dnew = - ctm -> b * sintheta + ctm -> d * costheta;
- ctm -> a = anew;
- ctm -> b = bnew;
- ctm -> c = cnew;
- ctm -> d = dnew;
- break;
-
- case TR_SCALING:
-
- ctm -> a *= x;
- ctm -> b *= x;
- ctm -> c *= y;
- ctm -> d *= y;
- break;
-
- case TR_TRANSLATION:
-
-
- ctm -> tx += ctm -> a * x + ctm -> c * y;
- ctm -> ty += ctm -> b * x + ctm -> d * y;
- break;
-
- default:
-
- break;
- }
- }
-
-
- /* Given a point (x,y) and the current transformation matrix ctm, returns
- the transformed point (x1,y1). */
- static void point_transf(struct ctm *ctm, float x, float y, float *x1, float *y1)
- {
- *x1 = ctm -> a * x + ctm -> c * y + ctm -> tx;
- *y1 = ctm -> b * x + ctm -> d * y + ctm -> ty;
- }
-
-
- /* Given the current transformation matrix and a bounding box,
- returns the transformed bounding box. */
- static void bb_new(struct ctm *ctm, struct bbox *bb, struct bbox *bbnew) {
-
- float x0,y0,x1,y1,x2,y2,x3,y3,xmin,xmax,ymin,ymax;
-
- xmin = ymin = 1.0e20;
- xmax = ymax = -1.0e20;
-
- point_transf(ctm, bb -> llx, bb -> lly, &x0, &y0);
- point_transf(ctm, bb -> urx, bb -> lly, &x1, &y1);
- point_transf(ctm, bb -> urx, bb -> ury, &x2, &y2);
- point_transf(ctm, bb -> llx, bb -> ury, &x3, &y3);
-
- xmin = min(xmin,x0); ymin = min(ymin,y0);
- xmin = min(xmin,x1); ymin = min(ymin,y1);
- xmin = min(xmin,x2); ymin = min(ymin,y2);
- xmin = min(xmin,x3); ymin = min(ymin,y3);
- xmax = max(xmax,x0); ymax = max(ymax,y0);
- xmax = max(xmax,x1); ymax = max(ymax,y1);
- xmax = max(xmax,x2); ymax = max(ymax,y2);
- xmax = max(xmax,x3); ymax = max(ymax,y3);
-
- bbnew -> llx = xmin;
- bbnew -> lly = ymin;
- bbnew -> urx = xmax;
- bbnew -> ury = ymax;
- }
-
-
- /* Given a pointer to a struct 'parse_result', returns width, height,
- hoffset, voffset of the picture, in inch. */
- VOID __regargs PSGetSize(struct parse_result *Result, float *width, float *height, float *hoff, float *voff)
- {
- float hscale=1.0, vscale=1.0,
- hscale_rxi=1.0, vscale_rxi=1.0,
- hoffset=0.0, voffset=0.0,
- angle=0.0;
-
- struct bbox bb, bbnew;
- struct ctm ctm;
-
- bb . llx = 0.0;
- bb . lly = 0.0;
- bb . urx = 8.0; /* default width = 8in */
- bb . ury = 11.0; /* default height = 11in */
-
- /* initialize the current transformation matrix with the identity matrix */
- ctm.a = ctm.d = 1.0;
- ctm.b = ctm.c = ctm.tx = ctm.ty = 0.0;
-
- if (Result -> gotcontrol & GOT_HSCALE)
- hscale = Result -> hscale;
-
- if (Result -> gotcontrol & GOT_VSCALE)
- vscale = Result -> vscale;
-
- if (Result -> gotcontrol & GOT_SCALE)
- hscale = vscale = Result -> scale;
-
- if (Result -> gotcontrol & GOT_HOFFSET)
- hoffset = Result -> hoffset;
-
- if (Result -> gotcontrol & GOT_VOFFSET)
- voffset = Result -> voffset;
-
- if (Result -> gotcontrol & GOT_ANGLE)
- angle = Result -> angle;
-
- if (Result -> gotcontrol & SUFFICIENT_PS_ARGS) {
- bb . llx = Result -> llx;
- bb . lly = Result -> lly;
- bb . urx = Result -> urx;
- bb . ury = Result -> ury;
-
- hscale_rxi = Result -> rwi / (10.0 * (bb . urx - bb . llx));
-
- if (Result -> gotcontrol & GOT_RHI)
- vscale_rxi = Result -> rhi / (10.0 * (bb. ury - bb . lly));
- else
- vscale_rxi = hscale_rxi;
- }
-
- /* Performs PostScript transformations */
- ctm_transf(&ctm, hoffset, voffset, TR_TRANSLATION);
- ctm_transf(&ctm, hscale, vscale, TR_SCALING);
- ctm_transf(&ctm, RAD(angle), 0.0f, TR_ROTATION);
- ctm_transf(&ctm, hscale_rxi, vscale_rxi, TR_SCALING);
- ctm_transf(&ctm, (float)-bb.llx, (float)-bb.lly,TR_TRANSLATION);
-
- bb_new(&ctm, &bb, &bbnew);
- *width = bbnew . urx - bbnew . llx;
- *height = bbnew . ury - bbnew . lly;
- *hoff = bbnew . llx;
- *voff = bbnew . lly;
-
- /* hsize & vsize define the clipping area; the clipping area isn't
- affected by scaling, translation or rotation. */
-
- if (Result -> gotcontrol & GOT_HSIZE)
- {
- *width = Result -> hsize ;
- *hoff = 0.0;
- }
-
- if (Result -> gotcontrol & GOT_VSIZE)
- {
- *height = Result -> vsize ;
- *voff = 0.0;
- }
- }
-
- /* Same of PSGetSize but returns width, height, hoffset, voffset
- in 'dot' or 'pixels', using 'Result->hres' and 'Result->vres'. */
- VOID __regargs PSGetSizeDot(struct parse_result *Result, LONG *width, LONG *height, LONG *hoff, LONG *voff)
- {
- float f_width, f_height, f_hoff, f_voff;
-
- PSGetSize(Result, &f_width, &f_height, &f_hoff, &f_voff);
- *width = (LONG)(f_width * (float) Result -> hres + 0.5);
- *height = (LONG)(f_height * (float) Result -> vres + 0.5);
- *hoff = (LONG)(f_hoff * (float) Result -> hres + 0.5);
- *voff = (LONG)(f_voff * (float) Result -> vres + 0.5);
- }
-